/**
 * CSV数据分析工具 - 输出HTML报告
 * 分析结果可以在浏览器中查看
 */

const fs = require('fs');
const Papa = require('papaparse');
const path = require('path');

/**
 * 分析CSV并生成HTML报告
 */
function analyzeToHtml(filePath, outputPath) {
    return new Promise((resolve, reject) => {
        console.log(`分析文件: ${filePath}`);
        console.log(`输出报告: ${outputPath}`);
        console.log('-'.repeat(50));

        let headers = [];
        const stats = {
            totalRows: 0,
            columns: [],
            columnTypes: {},
            columnStats: {},
            missingValues: {},
            sampleData: []
        };

        let rowCount = 0;
        const sampleSize = 10000;

        const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });

        Papa.parse(stream, {
            header: true,
            dynamicTyping: false,
            skipEmptyLines: true,
            
            step: function(result, parser) {
                rowCount++;

                // 初始化列信息
                if (rowCount === 1 && result.meta.fields) {
                    stats.columns = result.meta.fields;
                    
                    result.meta.fields.forEach(col => {
                        stats.columnStats[col] = {
                            numeric: [],
                            text: [],
                            empty: 0
                        };
                        stats.missingValues[col] = 0;
                        stats.columnTypes[col] = 'unknown';
                    });
                }

                // 收集样本数据（前10行用于显示）
                if (rowCount <= 10) {
                    stats.sampleData.push(result.data);
                }

                // 分析数据（采样前10000行）
                if (rowCount <= sampleSize) {
                    stats.columns.forEach(col => {
                        const value = result.data[col];

                        if (value === null || value === undefined || value === '') {
                            stats.missingValues[col]++;
                            stats.columnStats[col].empty++;
                        } else {
                            const numValue = parseFloat(value);
                            if (!isNaN(numValue)) {
                                stats.columnStats[col].numeric.push(numValue);
                            } else {
                                stats.columnStats[col].text.push(value);
                            }
                        }
                    });
                } else if (rowCount === sampleSize + 1) {
                    // 采样完成后停止详细分析，只统计行数
                    parser.abort();
                }

                if (rowCount % 50000 === 0) {
                    process.stdout.write(`\r已分析: ${rowCount.toLocaleString()} 行`);
                }
            },

            complete: function() {
                // 如果是提前终止，需要继续统计剩余行数
                if (rowCount < 50000) {
                    stats.totalRows = rowCount;
                    finishAnalysis();
                } else {
                    // 重新快速统计总行数
                    console.log('\n\n正在统计总行数...');
                    countTotalRows(filePath).then(total => {
                        stats.totalRows = total;
                        finishAnalysis();
                    });
                }

                function finishAnalysis() {
                    // 确定列类型
                    stats.columns.forEach(col => {
                        const colStats = stats.columnStats[col];
                        if (colStats.numeric.length > colStats.text.length) {
                            stats.columnTypes[col] = 'numeric';
                        } else if (colStats.text.length > 0) {
                            stats.columnTypes[col] = 'text';
                        }
                    });

                    console.log('\n\n生成HTML报告...');
                    
                    // 生成HTML
                    const html = generateHtmlReport(stats, filePath, sampleSize);
                    fs.writeFileSync(outputPath, html, 'utf-8');
                    
                    console.log(`\n✅ 报告已生成: ${outputPath}`);
                    console.log(`\n双击打开该文件即可在浏览器中查看！`);
                    
                    resolve(stats);
                }
            },

            error: function(error) {
                console.error('分析错误:', error);
                reject(error);
            }
        });
    });
}

/**
 * 快速统计总行数
 */
function countTotalRows(filePath) {
    return new Promise((resolve) => {
        let count = 0;
        const stream = fs.createReadStream(filePath, { encoding: 'utf-8' });
        
        Papa.parse(stream, {
            header: true,
            step: function() {
                count++;
                if (count % 50000 === 0) {
                    process.stdout.write(`\r已统计: ${count.toLocaleString()} 行`);
                }
            },
            complete: function() {
                console.log('');
                resolve(count);
            }
        });
    });
}

/**
 * 生成HTML报告
 */
function generateHtmlReport(stats, filePath, sampleSize) {
    const fileName = path.basename(filePath);
    const fileSize = (fs.statSync(filePath).size / (1024 * 1024)).toFixed(2);
    
    return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSV分析报告 - ${fileName}</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            padding: 20px;
            line-height: 1.6;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            overflow: hidden;
        }
        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        .header h1 {
            font-size: 2em;
            margin-bottom: 10px;
        }
        .header p {
            opacity: 0.9;
            font-size: 1.1em;
        }
        .content {
            padding: 30px;
        }
        .section {
            margin-bottom: 30px;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 10px;
            border-left: 4px solid #667eea;
        }
        .section h2 {
            color: #333;
            margin-bottom: 15px;
            font-size: 1.5em;
        }
        .info-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
        }
        .info-card {
            background: white;
            padding: 15px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }
        .info-card .label {
            color: #666;
            font-size: 0.9em;
            margin-bottom: 5px;
        }
        .info-card .value {
            color: #667eea;
            font-size: 1.8em;
            font-weight: bold;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            background: white;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
        }
        th, td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #e0e0e0;
        }
        th {
            background: #667eea;
            color: white;
            font-weight: 600;
        }
        tr:hover {
            background: #f5f5f5;
        }
        .badge {
            display: inline-block;
            padding: 4px 12px;
            border-radius: 12px;
            font-size: 0.85em;
            font-weight: 600;
        }
        .badge-numeric {
            background: #e3f2fd;
            color: #1976d2;
        }
        .badge-text {
            background: #f3e5f5;
            color: #7b1fa2;
        }
        .badge-unknown {
            background: #fce4ec;
            color: #c2185b;
        }
        .progress-bar {
            background: #e0e0e0;
            border-radius: 10px;
            height: 20px;
            overflow: hidden;
            margin-top: 5px;
        }
        .progress-fill {
            background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
            height: 100%;
            transition: width 0.3s;
        }
        .footer {
            text-align: center;
            padding: 20px;
            color: #666;
            background: #f8f9fa;
        }
        .stat-number {
            font-size: 1.2em;
            font-weight: bold;
            color: #667eea;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>📊 CSV数据分析报告</h1>
            <p>文件: ${fileName}</p>
        </div>

        <div class="content">
            <!-- 基本信息 -->
            <div class="section">
                <h2>📋 基本信息</h2>
                <div class="info-grid">
                    <div class="info-card">
                        <div class="label">文件大小</div>
                        <div class="value">${fileSize} MB</div>
                    </div>
                    <div class="info-card">
                        <div class="label">总行数</div>
                        <div class="value">${stats.totalRows.toLocaleString()}</div>
                    </div>
                    <div class="info-card">
                        <div class="label">列数</div>
                        <div class="value">${stats.columns.length}</div>
                    </div>
                    <div class="info-card">
                        <div class="label">分析行数</div>
                        <div class="value">${Math.min(stats.totalRows, sampleSize).toLocaleString()}</div>
                    </div>
                </div>
            </div>

            <!-- 列信息 -->
            <div class="section">
                <h2>📊 列信息详情</h2>
                <table>
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>列名</th>
                            <th>数据类型</th>
                            <th>缺失值</th>
                            <th>缺失率</th>
                            <th>统计信息</th>
                        </tr>
                    </thead>
                    <tbody>
                        ${stats.columns.map((col, idx) => {
                            const type = stats.columnTypes[col];
                            const missing = stats.missingValues[col];
                            const missingPercent = ((missing / Math.min(stats.totalRows, sampleSize)) * 100).toFixed(2);
                            const colStats = stats.columnStats[col];
                            
                            let typeClass = 'badge-unknown';
                            if (type === 'numeric') typeClass = 'badge-numeric';
                            if (type === 'text') typeClass = 'badge-text';
                            
                            let statsInfo = '';
                            if (type === 'numeric' && colStats.numeric.length > 0) {
                                const numbers = colStats.numeric;
                                const min = Math.min(...numbers);
                                const max = Math.max(...numbers);
                                const avg = (numbers.reduce((a, b) => a + b, 0) / numbers.length).toFixed(2);
                                statsInfo = `最小: ${min.toFixed(2)}<br>最大: ${max.toFixed(2)}<br>平均: ${avg}`;
                            } else if (type === 'text') {
                                const uniqueCount = new Set(colStats.text).size;
                                statsInfo = `唯一值: ${uniqueCount}`;
                            }
                            
                            return `
                                <tr>
                                    <td>${idx + 1}</td>
                                    <td><strong>${col}</strong></td>
                                    <td><span class="badge ${typeClass}">${type === 'numeric' ? '数值' : type === 'text' ? '文本' : '未知'}</span></td>
                                    <td>${missing.toLocaleString()}</td>
                                    <td>
                                        ${missingPercent}%
                                        <div class="progress-bar">
                                            <div class="progress-fill" style="width: ${missingPercent}%"></div>
                                        </div>
                                    </td>
                                    <td>${statsInfo}</td>
                                </tr>
                            `;
                        }).join('')}
                    </tbody>
                </table>
            </div>

            <!-- 样本数据 -->
            <div class="section">
                <h2>👁️ 数据预览（前10行）</h2>
                <div style="overflow-x: auto;">
                    <table>
                        <thead>
                            <tr>
                                ${stats.columns.map(col => `<th>${col}</th>`).join('')}
                            </tr>
                        </thead>
                        <tbody>
                            ${stats.sampleData.map(row => `
                                <tr>
                                    ${stats.columns.map(col => `<td>${row[col] || '<em style="color: #999;">空</em>'}</td>`).join('')}
                                </tr>
                            `).join('')}
                        </tbody>
                    </table>
                </div>
            </div>

            <!-- 缺失值汇总 -->
            <div class="section">
                <h2>⚠️ 缺失值汇总</h2>
                ${Object.entries(stats.missingValues)
                    .filter(([col, count]) => count > 0)
                    .sort((a, b) => b[1] - a[1])
                    .map(([col, count]) => {
                        const percent = ((count / Math.min(stats.totalRows, sampleSize)) * 100).toFixed(2);
                        return `
                            <div style="margin-bottom: 15px;">
                                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                                    <strong>${col}</strong>
                                    <span class="stat-number">${count.toLocaleString()} (${percent}%)</span>
                                </div>
                                <div class="progress-bar">
                                    <div class="progress-fill" style="width: ${percent}%"></div>
                                </div>
                            </div>
                        `;
                    }).join('') || '<p style="color: #666;">✅ 没有缺失值</p>'}
            </div>
        </div>

        <div class="footer">
            <p>报告生成时间: ${new Date().toLocaleString('zh-CN')}</p>
            <p>CSV大文件处理项目 - Papa Parse数据分析</p>
        </div>
    </div>
</body>
</html>`;
}

/**
 * 主函数
 */
async function main() {
    const csvFiles = [
        'output/基本设施.csv',
        'output/设施集合.csv'
    ];

    console.log('='.repeat(50));
    console.log('CSV分析工具 - 生成HTML报告');
    console.log('='.repeat(50));

    console.log('\n可用的CSV文件:');
    csvFiles.forEach((file, idx) => {
        try {
            const stats = fs.statSync(file);
            const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
            console.log(`${idx + 1}. ${file} (${sizeMB} MB)`);
        } catch (e) {
            console.log(`${idx + 1}. ${file} (文件不存在)`);
        }
    });

    // 默认分析第一个文件
    const inputFile = csvFiles[0];
    const outputFile = 'output/分析报告.html';

    console.log(`\n开始分析: ${inputFile}\n`);

    try {
        await analyzeToHtml(inputFile, outputFile);
        
        console.log('\n分析完成！');
        console.log(`\n📄 HTML报告: ${outputFile}`);
        console.log('\n💡 提示: 双击 ${outputFile} 在浏览器中查看报告');
        
    } catch (error) {
        console.error('分析失败:', error);
    }
}

// 如果直接运行此脚本
if (require.main === module) {
    main();
}

module.exports = { analyzeToHtml };

